
package nccloud.web.arap.amortization.action;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import nc.vo.arap.amortization.AggAmortizationVO;
import nc.vo.arap.amortization.AmortizationBVO;
import nc.vo.arap.amortization.AmortizationCVO;
import nc.vo.arap.amortization.AmortizationVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.ISuperVO;
import nc.vo.pub.VOStatus;
import nc.vo.pubapp.pattern.model.transfer.bill.ClientBillCombinServer;
import nccloud.framework.core.exception.ExceptionUtils;
import nccloud.framework.core.util.GridCompareUtils;
import nccloud.framework.service.ServiceLocator;
import nccloud.framework.web.action.itf.ICommonAction;
import nccloud.framework.web.container.IRequest;
import nccloud.framework.web.ui.pattern.extbillcard.ExtBillCard;
import nccloud.framework.web.ui.pattern.extbillcard.ExtBillCardOperator;
import nccloud.itf.arap.amortization.aggamortizationvo.IAmortizationvoService;

/**
* @description 一主多子保存
* @version ncc1.0
**/
public class SaveAction implements ICommonAction {

    @Override
    public Object doAction(IRequest request) {
        try {
            // 执行
            ExtBillCardOperator operator = new ExtBillCardOperator();
            nc.vo.arap.amortization.AggAmortizationVO bill = operator.toBill(request);
            // 差异更新
            ExtBillCard orignCard = operator.toCard(bill);
            operator.setOriginBillcard(orignCard);
            // 执行具体逻辑
            nc.vo.arap.amortization.AggAmortizationVO ret = this.excute1(bill);
            // 转换
            ExtBillCard retCard = operator.toCard(ret);

            // 差异比较(解决网络传输过程中，压缩解压缩效率问题)
            ExtBillCard finalBillCard = GridCompareUtils.compareExtBillCardGrid(operator.getOriginBillcard(), retCard);

            return finalBillCard;
        } catch (Exception e) {
            ExceptionUtils.wrapException(e);
        }
        return null;
    }

    private nc.vo.arap.amortization.AggAmortizationVO excute1(nc.vo.arap.amortization.AggAmortizationVO bill) {
        try {
            IAmortizationvoService service = ServiceLocator.find(IAmortizationvoService.class);
            nc.vo.arap.amortization.AggAmortizationVO retVO = null;
            if (bill.getParentVO().getStatus() == VOStatus.NEW) {
                this.beforeProcess(bill);// 公共的
                retVO = service.insertsave(bill);
            } else {
                retVO = service.updatesave(new nc.vo.arap.amortization.AggAmortizationVO[] { bill })[0];
            }
            // 保留原始数据属性
            // 公共的
            ClientBillCombinServer<nc.vo.arap.amortization.AggAmortizationVO> util = new ClientBillCombinServer<>();
            util.combine(this.filterDeleteBodyData(new nc.vo.arap.amortization.AggAmortizationVO[] { bill }), new nc.vo.arap.amortization.AggAmortizationVO[] { retVO });
            return bill;
        } catch (BusinessException e) {
            ExceptionUtils.wrapException(e);
        }
        return null;
    }

    /**
    * 执行前补全数据,将主键补齐
    *
    * @param bill
    */
    private void beforeProcess(nc.vo.arap.amortization.AggAmortizationVO bill) {
        String primaryKey = bill.getParentVO().getPrimaryKey();
        this.setPrimaryKey((nc.vo.arap.amortization.AmortizationBVO[]) bill.getChildren(nc.vo.arap.amortization.AmortizationBVO.class), primaryKey);
        this.setPrimaryKey((nc.vo.arap.amortization.AmortizationCVO[]) bill.getChildren(nc.vo.arap.amortization.AmortizationCVO.class), primaryKey);
    }

    /**
    * 设置子表中表头主键数据
    *
    * @param childrenVOs
    * @param primaryKey
    */
    private void setPrimaryKey(CircularlyAccessibleValueObject[] childrenVOs, String primaryKey) {
        for (CircularlyAccessibleValueObject childrenVO : childrenVOs) {
            if (childrenVO.getStatus() == VOStatus.NEW) {
                childrenVO.setAttributeValue("pk_amortization", primaryKey);
            }
        }
    }

    /**
    * 过滤状态=3的，未被删除的数据
    *
    * @param bill
    */
    private  nc.vo.arap.amortization.AggAmortizationVO[] filterDeleteBodyData( nc.vo.arap.amortization.AggAmortizationVO[] bills) {
        for ( nc.vo.arap.amortization.AggAmortizationVO bill : bills) {
            this.filterDeleteBodyData(bill, nc.vo.arap.amortization.AmortizationBVO.class);
            this.filterDeleteBodyData(bill, nc.vo.arap.amortization.AmortizationCVO.class);
        }
        return bills;
    }

    private void filterDeleteBodyData(nc.vo.arap.amortization.AggAmortizationVO bill, Class<? extends ISuperVO> clazz) {
        List<ISuperVO> normal = new ArrayList<ISuperVO>();
        ISuperVO[] childs = bill.getChildren(clazz);
        for (ISuperVO child : childs) {
            if (child.getStatus() != VOStatus.DELETED) {
                normal.add(child);
            }
        }
        if (normal != null && normal.size() > 0) {
            ISuperVO[] ret = (ISuperVO[]) Array.newInstance(normal.get(0).getClass(), normal.size());
            bill.setChildren(clazz, normal.toArray(ret));
        }
    }
}
